﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ChessEngine.Native
{
    public enum PieceColor : sbyte
    {
        None = 0,
        White = 1,
        Black = -1
    }

    public enum PieceType : byte
    {
        King = 0,
        Queen = 1,
        Rook = 2,
        Bishop = 3,
        Knight = 4,
        Pawn = 5,
        None = 6
    }

    public enum MoveType : byte
    {
        Normal,
        Capture,
        Castle,
        EnPassant
    }

    public enum StateFlags : uint
    {
        NONE = 0,

        //////////////////////////////////////////////////////////////////////////
        // Persistent States
        //////////////////////////////////////////////////////////////////////////

        // Move Conditions
        BLACK_CHECK = 0x00000001,
        BLACK_MATE = 0x00000002,
        WHITE_CHECK = 0x00000004,
        WHITE_MATE = 0x00000008,

        // Castling Conditions
        WHITE_CASTLED = 0x00000010,
        BLACK_CASTLED = 0x00000020,

        B_L_ROOK_MOVED = 0x00000040,
        B_R_ROOK_MOVED = 0x00000080,
        B_KING_MOVED = 0x00000100,

        W_L_ROOK_MOVED = 0x00000200,
        W_R_ROOK_MOVED = 0x00000400,
        W_KING_MOVED = 0x00000800,

        STALEMATE = 0x00001000,

        //////////////////////////////////////////////////////////////////////////

        //////////////////////////////////////////////////////////////////////////
        // Temporal Flags
        //////////////////////////////////////////////////////////////////////////

        EN_PASSANT = 0x00002000,
        PROMOTED = 0x00004000,
        CASTLED = 0x00008000

        //////////////////////////////////////////////////////////////////////////
    }

    [StructLayout(LayoutKind.Sequential)]
    [DebuggerDisplay("{Color} - {Type}")]
    public struct Piece
    {
        public PieceColor Color;
        public PieceType Type;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Move
    {
        // 4 bytes
        public Piece Piece1;
        public byte SrcPos1;
        public byte DestPos1;

        // 2 bytes
        public byte SrcPos2;
        public byte DestPos2;

        // 2 bytes
        public PieceType Captured;
        public MoveType Type;

        // 5 bytes
        public uint Flags;
        public byte EnPassantPosition;

        // 2 bytes
        public byte NumWhiteMoves;
        public byte NumBlackMoves;

        public byte Padding;
    }

    public interface IEngine : IDisposable
    {
        bool IsWhiteMate { get; }
        bool IsBlackMate { get; }
        bool IsCheckmate { get; }
        bool IsStalemate { get; }
        bool IsGameOver { get; }
        PieceColor WhoseMove { get; }

        List<Move> GetMoves();
        void DoMove(Move m);
        Move DoAIMove();

        Piece GetPieceAt(int col, int row);
        PieceType GetPieceTypeAt(int col, int row);
        PieceColor GetPieceColorAt(int col, int row);
    }
}
